<?php

namespace App\Http\Requests;

use App\Models\Patient;
use Illuminate\Database\Query\Builder;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

class HpiSubStoreRequest extends FormRequest
{
    protected $drug;

    /**
     * Prepare the data for validation.
     * @return void
     */
    protected function prepareForValidation()
    {
        $this->drug = app('field')->get('drug');
    }

    /**
     * Determine if the user is authorized to make this request.
     * @return bool
     */
    public function authorize()
    {
        return \Auth::check();
    }

    /**
     * Get the validation rules that apply to the request.
     * @return array
     */
    public function rules()
    {
        return [
            'record_id'   => [
                'required', 'integer', 'min:1',
                Rule::exists('st_medical_records', 'id')->where(function (Builder $query) {
                    $query->whereNull('deleted_at');
                    $user = \Auth::user();
                    if ($user instanceof Patient) {
                        $query->where(['patient_id' => $user->id]);
                    } elseif (!$user->isDoctorsAdmin() && !$user->isAdmin()) {
                        $query->where(['doctor_id' => $user->id]);
                    }
                }),
            ],
            'started_at'  => 'before_or_equal:now',
            'inducement'  => 'in:1,2,3,4',
            'clinic_site' => 'string|max:20',
            'symptoms'    => [
                'array',
                'max:5',
                Rule::exists('tn_dic_complain', 'name')->where(function (Builder $query) {
                    $query->where(['isdel' => 0]);
                }),
            ],
            'symptoms.*'  => 'string',

            'before_treatment.fbg.low'    => 'nullable|numeric|min:0.1|max:50|decimal:1',
            'before_treatment.fbg.high'   => 'nullable|numeric|min:0.1|max:50|decimal:1',
            'before_treatment.2hpbg.low'  => 'nullable|numeric|min:0.1|max:50|decimal:1',
            'before_treatment.2hpbg.high' => 'nullable|numeric|min:0.1|max:50|decimal:1',
            'before_treatment.hba1c'      => 'numeric|min:0.1|max:99.9|decimal:1',
            'after_treatment.fbg.low'     => 'nullable|numeric|min:0.1|max:50|decimal:1',
            'after_treatment.fbg.high'    => 'nullable|numeric|min:0.1|max:50|decimal:1',
            'after_treatment.2hpbg.low'   => 'nullable|numeric|min:0.1|max:50|decimal:1',
            'after_treatment.2hpbg.high'  => 'nullable|numeric|min:0.1|max:50|decimal:1',

            'diagnose'   => [
                'array',
                Rule::exists('st_disease_dictionary', 'id')->where(function (Builder $query) {
                    $query->whereNull('deleted_at');
                }),
            ],
            'diagnose.*' => 'integer|min:1|distinct',

            'medication'                              => 'nullable|array',
            'medication.*.name'                       => [
                'required_with:medication.*',
                Rule::exists('st_drug_dictionary', 'name')->where(function (Builder $query) {
                    $query->whereNull('deleted_at');
                }),
            ],
            'medication.*.dosage.type'                => 'in:' . implode(',', $this->drug['dosage'][2]['type']),
            'medication.*.dosage.value'               => 'numeric|min:0|max:999|decimal:2',
            'medication.*.dosage.values'              => 'array|min:1|max:4',
            'medication.*.dosage.values.morning'      => 'numeric|decimal:2|min:0|max:999',
            'medication.*.dosage.values.atnoon'       => 'numeric|decimal:2|min:0|max:999',
            'medication.*.dosage.values.evening'      => 'numeric|decimal:2|min:0|max:999',
            'medication.*.dosage.values.before_sleep' => 'numeric|decimal:2|min:0|max:999',
            'medication.*.dosage.unit'                => 'in:' . implode(',', $this->drug['dosage'][2]['unit']),
            'medication.*.start_time'                 => 'date',
            'medication.*.end_time'                   => 'date|after_or_equal:medication.*.start_time',
            'medication.*.usage'                      => 'in:' . implode(',', $this->drug['usage'][2]),
            'medication.*.frequency'                  => 'in:' . implode(',', $this->drug['frequency'][2]),
            'medication.*.remark'                     => 'string|max:50',

            'cn_medication.*.drugs.*.name'   => [
                'string',
                Rule::exists('st_drug_dictionary', 'name')->where(function (Builder $query) {
                    $query->whereNull('deleted_at');
                }),
            ],
            'cn_medication.*.type'           => 'required|in:1,3',
            'cn_medication.*.drugs.*.weight' => 'required_if:cn_medication.*.type,1|numeric|min:0|max:999',
            'cn_medication.*.usage'          => 'required_if:cn_medication.*.type,1|in:' . implode(',',
                    $this->drug['usage'][1]),
            'cn_medication.*.dosage'         => 'required_if:cn_medication.*.type,1|in:' . implode(',',
                    $this->drug['dosage'][1]['type']),
            'cn_medication.*.frequency'      => 'required_if:cn_medication.*.type,1|in:' . implode(',',
                    $this->drug['frequency'][1]),
            'cn_medication.*.dose'           => 'required_if:cn_medication.*.type,1|integer|min:0|max:999',

            'cn_medication.*.name'               => 'required_if:cn_medication.*.type,3',
            'cn_medication.*.start_time'         => 'nullable|date',
            'cn_medication.*.end_time'           => 'nullable|date',
            'cn_medication.*.times_per_day'      => 'required_if:cn_medication.*.type,3|integer|min:1',
            'cn_medication.*.quantity_per_times' => 'required_if:cn_medication.*.type,3|integer|min:1',
            'cn_medication.*.quantity_unit'      => 'required_if:cn_medication.*.type,3|in:粒,片,袋',
            'cn_medication.*.total'              => 'required_if:cn_medication.*.type,3|integer|min:1',

            //  首诊还是复诊
            'type'                               => 'in:1,2',
        ];
    }

    public function messages()
    {
        return [
            'record_id.required'  => '缺少病历ID',
            'record_id.integer'   => '病历ID 必须是整数。',
            'record_id.min'       => '病历ID 必须大于等于 :min。',
            'record_id.exists'    => '病历 不存在或无修改该病历的权限。',
            'diagnose.*.integer'  => '诊断名称 必须是一个整数。',
            'diagnose.*.min'      => '诊断名称 必须大于等于 :min。',
            'diagnose.*.distinct' => '诊断名称 已经存在。',
            'diagnose.*.exists'   => '您选择了不存在的 诊断名称。',

            'before_treatment.*.*.numeric'   => '血糖值 必须是一个数字。',
            'before_treatment.*.*.min'       => '血糖值 必须大于等于 :min。',
            'before_treatment.*.*.max'       => '血糖值 不能大于 :max。',
            'before_treatment.*.*.decimal'   => '血糖值 只能保留一位小数。',
            'before_treatment.hba1c.numeric' => 'HbA1c值 必须是一个数字。',
            'before_treatment.hba1c.min'     => 'HbA1c值 必须大于等于 :min。',
            'before_treatment.hba1c.max'     => 'HbA1c值 不能大于 :max。',
            'before_treatment.hba1c.decimal' => 'HbA1c值 只能保留一位小数。',

            'medication.*.name.required_with'          => '药物名称 不能为空。',
            'medication.*.name.exists'                 => '药物名称 不存在。',
            'medication.*.dosage.value.required_if'    => '每次剂量的剂量值 不能为空。',
            'medication.*.dosage.value.numeric'        => '剂量值 必须是一个数字。',
            'medication.*.dosage.value.decimal'        => '剂量值 只能保留一位小数。',
            'medication.*.dosage.value.min'            => '剂量值 必须大于等于 :min。',
            'medication.*.dosage.value.max'            => '剂量值 最大 :max。',
            'medication.*.dosage.values.*.required_if' => '分次剂量的剂量值 不能为空。',
            'medication.*.dosage.values.*.numeric'     => '剂量值 必须是一个数字。',
            'medication.*.dosage.values.*.decimal'     => '剂量值 只能保留一位小数。',
            'medication.*.dosage.values.*.min'         => '剂量值 必须大于等于 :min。',
            'medication.*.dosage.values.*.max'         => '剂量值 不能大于 :max。',
            'medication.*.start_time.date'             => '无效的时间值。',
            'medication.*.start_time.before_or_equal'  => '无效的时间值，时间值不能晚于现在。',
            'medication.*.end_time.date'               => '无效的时间值。',
            'medication.*.end_time.after_or_equal'     => '结束时间 不能小于 开始时间。',
            'medication.*.end_time.before_or_equal'    => '无效的时间值，时间值不能晚于现在。',
            'medication.*.usage.in'                    => '药品 用法取值错误。',
            'medication.*.frequency.in'                => '药品 使用频次取值错误。',

            'remark.max' => '备注最大 :max 个字符',
        ];
    }
}
